package com.platform.core.service.impl;

import cn.hutool.core.util.StrUtil;
import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.platform.comm.service.impl.CommonBizImpl;
import com.platform.core.repository.SysDataStandardRepository;
import com.querydsl.core.BooleanBuilder;
import com.platform.comm.dto.DtoMapper;
import com.platform.comm.entity.CommDataInfoEntity;
import com.platform.comm.jwt.JwtTokenUtil;
import com.platform.comm.jwt.TokenInfoUtil;
import com.platform.comm.service.ICommDataInfoBiz;
import com.platform.comm.web.results.PageListJsonResult;
import com.platform.dto.SysDataStandardDto;
import com.platform.core.entity.QSysDataStandardEntity;
import com.platform.core.entity.SysDataStandardEntity;
import com.platform.core.service.SysDataStandardBiz;
import io.micrometer.core.instrument.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.utils.Lists;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.querydsl.QSort;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * Description: NcloudSysDataStandard-业务接口实现类
 *
 * @author Coder
 */
@Slf4j
@Service
public class SysDataStandardBizImpl extends CommonBizImpl<SysDataStandardRepository, SysDataStandardEntity, String> implements SysDataStandardBiz {

    private final QSysDataStandardEntity qSysDataStandard = QSysDataStandardEntity.sysDataStandardEntity;
    private final DtoMapper mapper;
    private final TokenInfoUtil tokenInfoUtil;
    private final ICommDataInfoBiz commDataInfoBiz;

    private final ThreadPoolTaskExecutor taskExecutor;

    public SysDataStandardBizImpl(SysDataStandardRepository sysDataStandardRepository, DtoMapper mapper,
                                  TokenInfoUtil tokenInfoUtil,ICommDataInfoBiz commDataInfoBiz,ThreadPoolTaskExecutor taskExecutor) {
        super(sysDataStandardRepository);
        this.mapper = mapper;
        this.tokenInfoUtil = tokenInfoUtil;
        this.commDataInfoBiz = commDataInfoBiz;
        this.taskExecutor = taskExecutor;
    }

    @Override
    public PageListJsonResult<SysDataStandardDto> search(Map<String, String> params, Pageable pageable){
        if (pageable.getSort().isUnsorted()) {
            pageable = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize(),
                    QSort.by(qSysDataStandard.sortNum.asc(),qSysDataStandard.createDate.desc()));
        }
        BooleanBuilder builder = new BooleanBuilder();
        if (StrUtil.isNotEmpty(params.get("name"))){
            builder.and(qSysDataStandard.name.contains(params.get("name")));
        }
        if (StrUtil.isNotEmpty(params.get("type"))){
            builder.and(qSysDataStandard.type.eq(params.get("type")));
        }
        if (StrUtil.isNotEmpty(params.get("code"))){
            builder.and(qSysDataStandard.code.contains(params.get("code")));
        }
        Page<SysDataStandardEntity> entities = queryByPage(builder, pageable);
        return new PageListJsonResult<>(entities.map(entity -> {
            SysDataStandardDto sysDataStandardDto = entity.toDto();
            return getFileListByAttach(sysDataStandardDto);
        }));
    }

    @Override
    public SysDataStandardDto detail(String id) {
        SysDataStandardDto temp = mapper.map(fetchById(id), SysDataStandardDto.class);
        return getFileListByAttach(temp);
    }
    public SysDataStandardDto getFileListByAttach(SysDataStandardDto temp){
        // 添加附件ids
        String attachments = temp.getAttachment();
        if (!Strings.isNullOrEmpty(attachments)) {
            String[] file = attachments.split(",");
            List<Map<String, String>> fileList = com.google.common.collect.Lists.newArrayList();
            for (String fileId : file) {
                CommDataInfoEntity commDataInfo = commDataInfoBiz.queryCommDataImpById(fileId);
                if (Objects.nonNull(commDataInfo)) {
                    Map<String, String> fileMap = Maps.newHashMap();
                    fileMap.put("id", fileId);
                    fileMap.put("fileName", commDataInfo.getFileName());
                    fileList.add(fileMap);
                }
            }
            temp.setFileList(fileList);
        }
        return temp;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysDataStandardDto req) {
        SysDataStandardEntity entity = mapper.map(req, SysDataStandardEntity.class);
        JwtTokenUtil.JwtUser jwtUser = tokenInfoUtil.getUser();
        entity.setCreateDate(LocalDateTime.now());
        entity.setCreateBy(jwtUser.getId());
        entity.setUpdateDate(LocalDateTime.now());
        entity.setUpdateBy(jwtUser.getId());
        entity.setFlag("0");
        List<String> attachIds = Lists.newArrayList();
        req.getFileList().forEach(attach -> {
            attachIds.add(attach.get("id"));
        });
        entity.setAttachment(Joiner.on(",").join(attachIds));
        saveEntity(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void modify(SysDataStandardDto req) {
        SysDataStandardEntity entity = fetchById(req.getId());
        mapper.map(req, entity);
        List<String> attachIds = com.google.common.collect.Lists.newArrayList();
        // 存储附件信息
        req.getFileList().forEach(attach -> {
            attachIds.add(attach.get("id"));
        });
        entity.setAttachment(Joiner.on(",").join(attachIds));
        entity.setUpdateDate(LocalDateTime.now());
        entity.setUpdateBy(tokenInfoUtil.getUserId());
        saveEntity(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void remove(String id){
        SysDataStandardEntity sysDataStandardEntity = fetchById(id);
        if (Objects.nonNull(sysDataStandardEntity) && StringUtils.isNotEmpty(sysDataStandardEntity.getAttachment())){
            String[] split = sysDataStandardEntity.getAttachment().split(",");
            taskExecutor.execute(() -> Arrays.asList(split).forEach(commDataInfoBiz::delete));

        }
        repository.deleteById(id);
    }
    @Override
    public long validCode(String id, String code,String type) {
        BooleanBuilder predict = builderDictValidCondition(id);
        predict.and(qSysDataStandard.code.eq(code));
        predict.and(qSysDataStandard.type.eq(type));
        return repository.count(predict);
    }

    @Override
    public long validName(String id, String groupName,String type) {
        BooleanBuilder predict = builderDictValidCondition(id);
        predict.and(qSysDataStandard.name.eq(groupName));
        predict.and(qSysDataStandard.type.eq(type));
        return repository.count(predict);
    }

    private BooleanBuilder builderDictValidCondition(String id) {
        BooleanBuilder predicate = new BooleanBuilder();
        if (!Strings.isNullOrEmpty(id)) {
            predicate.and(qSysDataStandard.id.ne(id));
        }
        return predicate;
    }
}
